package com.example.multi.data.provider.service.yiqing.impl;

import com.example.multi.data.provider.client.YiqingClient;
import com.example.multi.data.provider.client.YiqingNewsClient;
import com.example.multi.data.provider.model.data.Showapi_res_body;
import com.example.multi.data.provider.model.data.Showapi_res_result;
import com.example.multi.data.provider.model.data.TodayDetailList;
import com.example.multi.data.provider.model.data.TodayStatictic;
import com.example.multi.data.provider.model.news.NewsList;
import com.example.multi.data.provider.model.vo.OptionVo;
import com.example.multi.data.provider.service.yiqing.IYiqingService;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class YiqingServiceImpl implements IYiqingService {
    private static final Logger log = LoggerFactory.getLogger(YiqingServiceImpl.class);
    private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static ExecutorService executor = Executors.newWorkStealingPool();
    @Value("${yiqing.showapi_appid}")
    private String showapi_appid;
    @Value("${yiqing.showapi_appsecret}")
    private String showapi_appsecret;
    @Autowired
    private YiqingClient yiqingClient;


    @Autowired
    private YiqingNewsClient yiqingNewsClient;

    @Override
    public Showapi_res_result query() {
        LocalDateTime now = LocalDateTime.now();
        String showapi_timestamp = dtf.format(now);
        String s = "showapi_appid" + showapi_appid + "showapi_timestamp" + showapi_timestamp + showapi_appsecret;
        String sign = DigestUtils.md5Hex(s.getBytes(StandardCharsets.UTF_8));
        Showapi_res_result result = yiqingClient.query(showapi_appid, showapi_timestamp, sign);
        return result;
    }

    @Override
    public Showapi_res_result queryProvince() {

        Showapi_res_result result = this.query();
        if (Objects.nonNull(result)) {
            Showapi_res_body resBody = result.getShowapi_res_body();
            if (Objects.nonNull(resBody)) {
                List<TodayDetailList> todayDetailList = resBody.getTodayDetailList();
                if (!CollectionUtils.isEmpty(todayDetailList)) {
                    List<CompletableFuture<TodayDetailList>> completableFutures = todayDetailList.stream().parallel().map(item -> CompletableFuture.supplyAsync(() -> {
                                return item;
                            }, executor).thenApplyAsync(i -> {
                                i.setCityList(new ArrayList<>());
                                i.setDangerAreas(new ArrayList<>());
                                return i;
                            }, executor))
                            .collect(Collectors.toList());
                    todayDetailList = completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
                    resBody.setTodayDetailList(todayDetailList);
                    result.setShowapi_res_body(resBody);
                }
            }

        }

        return result;
    }

    @Override
    public List<OptionVo> queryProvinceSimple() {
        List<OptionVo> optionVos = new ArrayList<>();
        Showapi_res_result result = this.queryProvince();

        if (Objects.nonNull(result) && Objects.nonNull(result.getShowapi_res_body()) && !CollectionUtils.isEmpty(result.getShowapi_res_body().getTodayDetailList())) {
            Date updateTime = result.getShowapi_res_body().getUpdateTime();
            List<TodayDetailList> todayDetailList = result.getShowapi_res_body().getTodayDetailList();
            optionVos = todayDetailList.stream().parallel().map(item -> {
                OptionVo optionVo = new OptionVo();
                optionVo.setName(item.getProvinceName());
                optionVo.setValue(String.valueOf(item.getCurrentConfirmedNum()));
                optionVo.setValue1(String.valueOf(item.getConfirmedNum()));
                optionVo.setCode(String.valueOf(item.getLocationId()));
                optionVo.setTime(sdf.format(updateTime));
                return optionVo;
            }).collect(Collectors.toList());

        }
        return optionVos;
    }

    @Override
    public TodayStatictic queryTodayStatictic() {
        Showapi_res_result result = this.query();
        TodayStatictic todayStatictic = null;
        if (Objects.nonNull(result) && Objects.nonNull(result.getShowapi_res_body())) {
            Showapi_res_body showapi_res_body = result.getShowapi_res_body();
            Date updateTime = showapi_res_body.getUpdateTime();
            if (Objects.nonNull(showapi_res_body.getTodayStatictic())) {
                todayStatictic = showapi_res_body.getTodayStatictic();
                todayStatictic.setUpdateTime(updateTime);
            }

        }
        return todayStatictic;
    }

    @Override
    public List<NewsList> queryNews() {
        LocalDateTime now = LocalDateTime.now();
        String showapi_timestamp = dtf.format(now);
        String s = "showapi_appid" + showapi_appid + "showapi_timestamp" + showapi_timestamp + showapi_appsecret;
        String sign = DigestUtils.md5Hex(s.getBytes(StandardCharsets.UTF_8));
        com.example.multi.data.provider.model.news.Showapi_res_result result = yiqingNewsClient.query(showapi_appid, showapi_timestamp, sign);
        List<NewsList> newsList = new ArrayList<>();
        if (Objects.nonNull(result) && Objects.nonNull(result.getShowapi_res_body()) && !CollectionUtils.isEmpty(result.getShowapi_res_body().getNewsList())) {
            newsList = result.getShowapi_res_body().getNewsList();
        }
        return newsList;
    }

}
